package cn.iocoder.yudao.module.ym.job;

import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.framework.web.config.WebProperties;
import cn.iocoder.yudao.module.infra.dal.dataobject.config.ConfigDO;
import cn.iocoder.yudao.module.infra.dal.mysql.config.ConfigMapper;
import cn.iocoder.yudao.module.infra.enums.*;
import cn.iocoder.yudao.module.infra.service.job.JobLogService;
import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApiImpl;
import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
import cn.iocoder.yudao.module.system.dal.mysql.dict.DictDataMapper;
import cn.iocoder.yudao.module.ym.controller.admin.ticketlog.vo.TicketLogSaveReqVO;
import cn.iocoder.yudao.module.ym.dal.dataobject.area.AreaDO;
import cn.iocoder.yudao.module.ym.dal.dataobject.ticket.TicketDO;
import cn.iocoder.yudao.module.ym.dal.dataobject.ticketlog.TicketLogDO;
import cn.iocoder.yudao.module.ym.dal.mysql.ticket.TicketMapper;
import cn.iocoder.yudao.module.ym.dal.mysql.ticketlog.TicketLogMapper;
import cn.iocoder.yudao.module.ym.service.ticketlog.TicketLogService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserNickname;
import static cn.iocoder.yudao.module.infra.enums.DictTypeConstants.YM_WORD_TEMP_TYPE;

/**
 * 扫描工单是否超时
 *
 * @author j-sentinel
 */
@Slf4j
@Component
public class TicketTimeOutJob implements JobHandler {

    @Resource
    private TicketMapper ticketMapper;

    @Resource
    private ConfigMapper configMapper;

    @Resource
    private NotifyMessageSendApiImpl notifyMessageSendApi;

    @Resource
    private WebProperties webProperties;

    @Resource
    private DictDataMapper dictDataMapper;

    @Resource
    private TicketLogMapper ticketLogMapper;

    @Override
    @TenantIgnore
    @Transactional
    public String execute(String param) {
        System.out.println("扫描工单超时-------------------------------"+param);

        LocalDateTime now = LocalDateTime.now();
        List<TicketDO> timeoutList = new ArrayList<>();


        List<TicketLogDO> insertList = new ArrayList<>();
        int ticketStatus = TicketStatusEnum.TIMEOUT.getCode();

        // 2. 获取待处理的工单
        List<TicketDO> ticketDOS = ticketMapper.selectList(new LambdaQueryWrapperX<TicketDO>()
                .eq(TicketDO::getTicketStatus, TicketStatusEnum.PENDING.getCode()).or()
                .eq(TicketDO::getTicketStatus,TicketStatusEnum.PROCESSING.getCode()));
        if(!ticketDOS.isEmpty()){
            for (TicketDO ticketDO : ticketDOS) {
                Long tenantId = ticketDO.getTenantId();
                LocalDateTime createTime = ticketDO.getCreateTime();
                Integer timeoutHour = ticketDO.getTimeoutHour(); //超时时长
                LocalDateTime localDateTime = createTime.plusHours(timeoutHour); //增加后的时间
                // 如果是重新派发 ，需要按照重新派发时间
                LocalDateTime redistributeTime = ticketDO.getRedistributeTime();
                if(redistributeTime != null){
                    localDateTime = redistributeTime.plusHours(timeoutHour); //重新派发增加后的时间
                }
                if(now.isAfter(localDateTime)){
                    //3. 超时处理
                    ticketDO.setTicketStatus(ticketStatus);
                    timeoutList.add(ticketDO);

                    //4. 插入日志
                    TicketLogDO ticketLogDO = new TicketLogDO();
                    ticketLogDO.setTicketId(ticketDO.getId());
                    ticketLogDO.setContent(String.format(TicketLogRecordConstants.TICKET_TIMEOUT, timeoutHour));
                    ticketLogDO.setTenantId(tenantId);
                    insertList.add(ticketLogDO);


                    //5. 发送站内信
                    Map<String, Object> templateParams = new HashMap<>();
                    templateParams.put("ticketNum", ticketDO.getTicketNumber());
                    templateParams.put("url", webProperties.getAdminUi().getUrl() + "/#/order/my");


                    NotifySendSingleToUserReqDTO notifySendSingleToUserReqDTO = new NotifySendSingleToUserReqDTO();
                    notifySendSingleToUserReqDTO.setUserId(ticketDO.getOperatorId());
                    notifySendSingleToUserReqDTO.setTemplateCode(YmMessageEnum.TICKET_TIMEOUT.getSmsTemplateCode());
                    notifySendSingleToUserReqDTO.setTemplateParams(templateParams);
                    notifySendSingleToUserReqDTO.setTenantId(tenantId);
                    notifyMessageSendApi.sendSingleMessageToAdminTenant(notifySendSingleToUserReqDTO);

                }

            }
            if(!timeoutList.isEmpty()){
                ticketMapper.updateBatch(timeoutList);
            }
            if(!insertList.isEmpty()){
                ticketLogMapper.insertBatch(insertList);
            }
        }

        return String.format("定时执行工单超时数量 %s 个",timeoutList.size());
    }

}
